#include <keyboard.h>
#include <constants.h>
#define BREAK_CODE 0xF0
#define LINEFEED_CODE 0x0A
#define CR_CODE 0x0D
#define E0_CODE 0xE0
#define SHIFT_CODE 0xF1
int key_press_flag;       // Keypress
volatile int break_code_flag;
int shift_key_flag;
int user_input;           // Input location entered by the user
char lastKey;
char keyboard_LUT[256] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 96, 0, 
0, 0, 0, 0, 0, 81, 49, 0, 0, 0, 90, 83, 65, 87, 50, 0, 
0, 67, 88, 68, 69, 52, 51, 0, 0, 32, 86, 70, 84, 82, 53, 0, 
0, 78, 66, 72, 71, 89, 54, 0, 0, 0, 77, 74, 85, 55, 56, 0, 
0, 44, 75, 73, 79, 48, 57, 0, 0, 46, 47, 76, 59, 80, 45, 0, 
0, 0, 39, 0, 91, 61, 0, 0, 0, 0, LINEFEED_CODE, 93, 0, 92, 0, 0, 
0, 0, 0, 0, 0, 0, 8, 0, 0, 49, 0, 52, 55, 0, 0, 0, 
48, 46, 50, 53, 54, 56, 27, 0, 0, 43, 51, 45, 42, 57, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
E0_CODE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
BREAK_CODE, SHIFT_CODE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
};


void keyboardInit(void){

//initialize keyboard (P1.4 -->CLOCK line, P1.5-->DATA line)
  P1SEL &= 0xCF;                // I/O for P1.4,1.5
  P1DIR &= 0xCF;                // input (P1.4,1.5)
  P1IES = 0x10;                 //Clock interupt on high to low transitions
  P1IE = 0x10;                  //Enable interupts on clock line
  P1IFG = 0x00;                 // Clear interrupt flag
  break_code_flag = 0;
  shift_key_flag = 0;
}

void Keyboard_interrupt(void) __interrupt[PORT1_VECTOR]
{
  char key;
  key_press_flag = 1;
  P1IE = 0x00;              // Disable interrupts
  key=get_scan();
  
  P1IFG = 0x00;             // Reset interrupt flag
  P1IE = 0x10; //0x04;              // Enable interrupts

  if (break_code_flag == 0){
    if (lastKey == E0_CODE && key != BREAK_CODE){
      if (key == LINEFEED_CODE){
        putChar(key);
        putChar(CR_CODE);
      }
    }
    else{
      switch(key){
        case BREAK_CODE : 
          break_code_flag = 1;
          break;
        case LINEFEED_CODE :
          putChar(key);
          putChar(CR_CODE);
          break;
        case E0_CODE :
          break;
    //    case keyboard_LUT[89] :
    //      shift_key_flag = 1;
    //      break;
        default :
          putChar(key);
          sendData(key);
          break;
      }
    }

  }
  else if (key!=BREAK_CODE){
    break_code_flag = 0;
  }
  lastKey = key;

        
//  if ((break_code_flag == 1) && (key != keyboard_LUT[240])){
//    break_code_flag = 0;
//    }
//  else {
//    if (key == keyboard_LUT[240]){
//      break_code_flag = 1;
//    }
//    else{
//      putChar(key);      //Prints Key on display
//    }
//  }
}

char get_scan(void)
{
  static int clk[50];
  static int arr[50];
  int i,j;
  char last;
  char key=0;
  for (i=0;i<50;i++)
  {
   clk[i]=P1IN&0x10;
   arr[i]=P1IN&0x20;
  }
 last=1;
 j=0;
 for (i=0;i<50;i++)
 {
   if (last&&(clk[i]==0)) //wait for a falling edge
   {
     if (arr[i]&0x20) //wait for 
     {
       key |= 1<<j;
     }
     j++;
   }
   last=!(clk[i]==0); //toggle last state
 }
 key=keyboard_LUT[key]; //match key      

 return(key);
}
